<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
		<title></title>
		<script src="./js/vue.js"></script>
		<script src="./js/uni.webview.1.5.4.js"></script>

		<style>
			.topvg {
				width: 100%;
				display: flex;
				height: 230px;
				background: linear-gradient(180deg, #111111, rgba(0, 0, 0, 0));
				position: fixed;
				top: 0px;
				left: 0px;
				color: white;
				z-index: 99;
				align-items: flex-start
			}

			.wbbg {
				background: #2b2b2b;
			}

			.btmvg {
				width: 100%;
				display: flex;
				height: 40%;
				background: linear-gradient(to bottom, rgba(0, 0, 0, 0), #111111);
				position: fixed;
				left: 0px;
				bottom: 0px;
				color: white;
				align-items: flex-end;
			}

			.btnitem {
				width: 60px;
				height: 60px;
				display: flex;
				align-items: center;
				justify-content: center;
				border-radius: 60px;
				background: rgba(207, 207, 207, 0.3);
			}
		</style>
	</head>
	<body style="padding: 0px;margin: 0px;">
		<!-- 创建一个根元素 -->
		<div style="width: 100%;height: 100vh;overflow-y: hidden;" id="home">
			
			<audio webkit-playsinline='true' playsinline='true' src="" id="bgyx_video_1"
				style="width: 100%;height: 180px;object-fit:cover;position:fixed;z-index:100;right:15px;top:50px;border-radius:8px;"
				autoplay controls></audio>
			
		</div>
		<script>
			// 将vue挂载到id为home的根元素上
			var vm = new Vue({
				el: "#home",
				data() {
					return {
						id: '',
						name: '',
						uid: '',
						uname: '',
						ip: '',
						srsUrl: '',
						avatarurl: '',
						showself: true,
						video: true,
						audio: true,
						videou: true,
						audiou: true,
						src: '',
						uservddata: '',
						myvddata: ''
					};
				},
				watch: {
					myvddata: function(v) {
						document.getElementById("bgyx_video_1").srcObject = v.stream
					},
					uservddata: function(v) {
						console.log(v)
						document.getElementById("bgyx_video_0").srcObject = v.stream
					},
				},
				methods: {
					changecamera: async function(e) {
						const type = this.myvddata.videoType
						let videoType = type
						if(videoType == "face"){
							videoType = "environment"
						}else{
							videoType = "face"
						}
						await this.myvddata.unpublish()
						this.publishStream({
							videoType,
							video:this.myvddata.video,
							audio:this.myvddata.audio,
						})
					},
					changeaudio: function(e) {
						this.myvddata.muteAudio(e)
						this.myvddata.audio = e
						this.sendMessage({
							type: "muteaudio",
							data: e
						})
					},
					changevideo: function(e) {
						this.myvddata.muteVideo(e)
						this.myvddata.video = e
						this.sendMessage({
							type: "mutevideo",
							data: e
						})
					},
					exit: async function() {
						try {
							await this.myvddata.unpublish()
							await this.uservddata.close()
						} catch (e) {
							//TODO handle the exception
						}
						this.sendMessage({
							type: "exit",
							data: {}
						})
					},
					getvideo: async function() {
						const ret = await navigator.mediaDevices.getUserMedia({
							video: true,
							audio: false
						})
						this.src = ret
						this.publishStream({
							video: true
						})

						setTimeout(() => {
							this.subStream()
						}, 5000)
					},
					subStream: async function() {
						const _this = this
						const roomId = "videocall"
						const id = this.id
						const pc = new RTCPeerConnection(null);
						pc.addTransceiver('audio', {
							direction: 'recvonly'
						});
						pc.addTransceiver('video', {
							direction: 'recvonly'
						});
						let offer = await pc.createOffer();
						let stream = new MediaStream();
						pc.ontrack = function(event) {
							console.log(event);
							stream.addTrack(event.track);
						};
						await pc.setLocalDescription(offer);
						let session = await new Promise(function(resolve, reject) {
							let data = {
								api: `${_this.srsUrl}/rtc/v1/play/`,
								tid: id,
								streamurl: `webrtc://${_this.ip}/${roomId}/${id}`,
								clientip: null,
								sdp: offer.sdp,
							};
							console.log('Generated offer: ', data);

							const xhr = new XMLHttpRequest();
							xhr.onload = function() {
								if (xhr.readyState !== xhr.DONE) return;
								if (xhr.status !== 200) return reject(xhr);
								const data = JSON.parse(xhr.responseText);
								console.log('Got answer: ', data);
								return data.code ? reject(xhr) : resolve(data);
							};
							xhr.open('POST', `${_this.srsUrl}/rtc/v1/play/`, true);
							xhr.setRequestHeader('Content-type', 'application/json');
							xhr.send(JSON.stringify(data));
						});
						await pc.setRemoteDescription(
							new RTCSessionDescription({
								type: 'answer',
								sdp: session.sdp
							}),
						);

						function close() {
							stream.getTracks().forEach(function(track) {
								track.stop();
								stream.removeTrack(track);
							});
							// stream.close()
							pc.close();
							document.getElementById("bgyx_video_0").srcObject = null
						}

						const vdata = {
							id,
							roomId,
							pc,
							stream,
							audio: true,
							video: true,
							close,
						};

						this.uservddata = vdata
					},
					publishStream: async function(options) {
						const _this = this
						const id = "this1uid"
						const roomId = 'videocall1'
						const pc = new RTCPeerConnection(null);
						pc.addTransceiver('audio', {
							direction: 'sendonly'
						});
						pc.addTransceiver('video', {
							direction: 'sendonly'
						});
						const stream = await this.getStreamLoc({
							audio: true,
							video: false
						})
						this.cameraType = options.videoType ? options.videoType : "environment"
						console.log(stream);
						stream.getTracks().forEach(function(track) {
							pc.addTrack(track);
							// if (track.kind === 'audio') {
							// 	if (options.audio === false) {
							// 		track.enabled = false;
							// 	}
							// }
							// if (track.kind === 'video') {
							// 	if (options.video === false) {
							// 		track.enabled = false;
							// 	}
							// }
						});
						let offer = await pc.createOffer();
						await pc.setLocalDescription(offer);

						let session = await new Promise(function(resolve, reject) {
							let data = {
								api: `${_this.srsUrl}/rtc/v1/publish/`,
								tid: id,
								streamurl: `webrtc://${_this.ip}/${roomId}/${id}`,
								clientip: null,
								sdp: offer.sdp,
							};
							console.log('Generated offer: ', data);

							const xhr = new XMLHttpRequest();
							xhr.onload = function() {
								if (xhr.readyState !== xhr.DONE) return;
								if (xhr.status !== 200) return reject(xhr);
								const data = JSON.parse(xhr.responseText);
								console.log('Got answer: ', data);
								if (data.code === 400) {
									resolve(false);
								}
								return data.code ? reject(xhr) : resolve(data);
							};
							xhr.open('POST', `${_this.srsUrl}/rtc/v1/publish/`, true);
							xhr.setRequestHeader('Content-type', 'application/json');
							xhr.send(JSON.stringify(data));
						});

						console.log(session);
						if (session === false) {
							return false;
						}
						await pc.setRemoteDescription(
							new RTCSessionDescription({
								type: 'answer',
								sdp: session.sdp
							}),
						);

						function muteAudio(type) {
							stream.getTracks().forEach(function(track) {
								if (track.kind === 'audio') {
									track.enabled = type ? type : false;
								}
							});
						}

						function muteVideo(type) {
							stream.getTracks().forEach(function(track) {
								if (track.kind === 'video') {
									track.enabled = type ? type : false;
								}
							});
						}


						async function unpublish() {
							try {
								stream.getTracks().forEach(function(track) {
									track.stop();
									stream.removeTrack(track);
								});
								// stream.close()
								pc.close();
								document.getElementById("bgyx_video_1").srcObject = null
							} catch (e) {
								//TODO handle the exception
							}
						}

						const vdata = {
							id: id,
							roomId: roomId,
							pc,
							stream,
							audio: options.audio == false ? false : true,
							video: options.video == false ? false : true,
							videoType: options.videoType ? options.videoType : "environment",
							muteAudio,
							muteVideo,
							unpublish,
						};

						this.myvddata = vdata

						document.getElementById("bgyx_video_1").srcObject = stream

						setTimeout(() => {
							_this.sendMessage({
								type: "pubvideodone",
								data: {}
							})
						}, 500)
					},
					getStreamLoc: async function(constraints) {
						if (navigator.mediaDevices.getUserMedia) {
							console.log('最新的标准API', navigator.mediaDevices.getUserMedia);
							const rs = await navigator.mediaDevices.getUserMedia(constraints)
							return rs
						} else if (navigator.webkitGetUserMedia) {
							console.log('webkit核心浏览器');
							const rs = await navigator.webkitGetUserMedia(constraints)
							return rs
						} else if (navigator.mozGetUserMedia) {
							console.log('firfox浏览器');
							const rs = await navigator.mozGetUserMedia(constraints);
							return rs
						} else if (navigator.getUserMedia) {
							console.log('旧版API');
							const rs = await navigator.getUserMedia(constraints);
							return rs
						} else {
							const rs = await navigator.mediaDevices.getUserMedia(constraints)
							return rs
						}
					},
					onMessage: async function(e) {
						let message = e
						if (typeof e != 'object') {
							message = JSON.parse(e)
						}

						console.log('HTML接收APP数据', JSON.stringify(message));

						const type = message.type
						const data = message.data
						if (type == "userpubdone") {
							this.subStream()
						}

						if (type == "changeuseraudio") {
							this.uservddata.audio = data
						}

						if (type == "changeuservideo") {
							this.uservddata.video = data
						}

						if (type == "close") {
							try {
								await this.myvddata.unpublish()
								await this.uservddata.close()
							} catch (e) {
								//TODO handle the exception
							}
							this.sendMessage({
								type: "closedone",
								data: {}
							})
						}



					},
					sendMessage: function(e) {
						uni.postMessage({
							data: e
						})
					}
				},
				mounted() {
					const _this = this
					let params = new URLSearchParams(window.location.search);
					let uid = params.get('uid');
					let uname = params.get('uname');
					let name = params.get('name');
					let id = params.get('id');
					let ip = params.get('ip');
					let srsUrl = decodeURIComponent(params.get('srsUrl'));
					let avatarurl = decodeURIComponent(params.get('avatarurl'));
					console.log(srsUrl, id);
					this.uid = uid
					this.uname = uname
					this.name = name
					this.id = id
					this.ip = ip
					this.srsUrl = srsUrl
					this.avatarurl = avatarurl

					// 监听数据
					window.parent.addEventListener("message", function(e) {
						console.log("YYYY", e)
						let ex = e.data
						if (ex.type == "WEB_INVOKE_APPSERVICE") {
							ex = ex.data.arg
						}
						_this.onMessage(ex)
					})

					this.publishStream({
						video: true,
						audio: true,
						videoType: 'face'
					})
				},
				created() {},
			});
		</script>
	</body>
</html>